package cn.zhz.springdoc.springboot.config.v3;

import org.apache.commons.lang3.StringUtils;
import org.springdoc.core.*;
import org.springdoc.core.customizers.OpenApiCustomiser;
import org.springdoc.core.customizers.OperationCustomizer;
import org.springdoc.core.customizers.RouterOperationCustomizer;
import org.springdoc.core.filters.OpenApiMethodFilter;
import org.springdoc.core.providers.SpringWebProvider;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Optional;

/**
 * @author ZHZ
 * @since 2022-11-16
 */
public class CustomerOpenApiWebMvcResource extends CustomerOpenApiResource {

    /**
     * Instantiates a new Open api web mvc resource.
     *
     * @param groupName                   the group name
     * @param openAPIBuilderObjectFactory the open api builder object factory
     * @param requestBuilder              the request builder
     * @param responseBuilder             the response builder
     * @param operationParser             the operation parser
     * @param operationCustomizers        the operation customizers
     * @param openApiCustomisers          the open api customisers
     * @param routerOperationCustomizers  the router operation customizers
     * @param methodFilters               the method filters
     * @param springDocConfigProperties   the spring doc config properties
     * @param springDocProviders          the spring doc providers
     */
    public CustomerOpenApiWebMvcResource(String groupName, ObjectFactory<OpenAPIService> openAPIBuilderObjectFactory, AbstractRequestService requestBuilder, GenericResponseService responseBuilder, OperationService operationParser, Optional<List<OperationCustomizer>> operationCustomizers, Optional<List<OpenApiCustomiser>> openApiCustomisers, Optional<List<RouterOperationCustomizer>> routerOperationCustomizers, Optional<List<OpenApiMethodFilter>> methodFilters, SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders) {
        super(groupName, openAPIBuilderObjectFactory, requestBuilder, responseBuilder, operationParser, operationCustomizers, openApiCustomisers, routerOperationCustomizers, methodFilters, springDocConfigProperties, springDocProviders);
    }

    /**
     * Instantiates a new Open api web mvc resource.
     *
     * @param openAPIBuilderObjectFactory the open api builder object factory
     * @param requestBuilder              the request builder
     * @param responseBuilder             the response builder
     * @param operationParser             the operation parser
     * @param operationCustomizers        the operation customizers
     * @param openApiCustomisers          the open api customisers
     * @param routerOperationCustomizers  the router operation customizers
     * @param methodFilters               the method filters
     * @param springDocConfigProperties   the spring doc config properties
     * @param springDocProviders          the spring doc providers
     */
    @Autowired
    public CustomerOpenApiWebMvcResource(ObjectFactory<OpenAPIService> openAPIBuilderObjectFactory, AbstractRequestService requestBuilder, GenericResponseService responseBuilder, OperationService operationParser, Optional<List<OperationCustomizer>> operationCustomizers, Optional<List<OpenApiCustomiser>> openApiCustomisers, Optional<List<RouterOperationCustomizer>> routerOperationCustomizers, Optional<List<OpenApiMethodFilter>> methodFilters, SpringDocConfigProperties springDocConfigProperties, SpringDocProviders springDocProviders) {
        super(openAPIBuilderObjectFactory, requestBuilder, responseBuilder, operationParser, operationCustomizers, openApiCustomisers, routerOperationCustomizers, methodFilters, springDocConfigProperties, springDocProviders);
    }

//    /**
//     * Openapi json string.
//     *
//     * @param request the request
//     * @param apiDocsUrl the api docs url
//     * @param locale the locale
//     * @return the string
//     * @throws JsonProcessingException the json processing exception
//     */
//    @Operation(hidden = true)
//    @GetMapping(value = API_DOCS_URL, produces = MediaType.APPLICATION_JSON_VALUE)
//    @Override
//    public String openapiJson(HttpServletRequest request, @Value(API_DOCS_URL) String apiDocsUrl, Locale locale)
//            throws JsonProcessingException {
//        return super.openapiJson(request, apiDocsUrl, locale);
//    }
//
//    /**
//     * Openapi yaml string.
//     *
//     * @param request the request
//     * @param apiDocsUrl the api docs url
//     * @param locale the locale
//     * @return the string
//     * @throws JsonProcessingException the json processing exception
//     */
//    @Operation(hidden = true)
//    @GetMapping(value = DEFAULT_API_DOCS_URL_YAML, produces = APPLICATION_OPENAPI_YAML)
//    @Override
//    public String openapiYaml(HttpServletRequest request, @Value(DEFAULT_API_DOCS_URL_YAML) String apiDocsUrl, Locale locale)
//            throws JsonProcessingException {
//        return super.openapiYaml(request, apiDocsUrl, locale);
//    }

    /**
     * Gets server url.
     *
     * @param request    the request
     * @param apiDocsUrl the api docs url
     * @return the server url
     */
    @Override
    protected String getServerUrl(HttpServletRequest request, String apiDocsUrl) {
        String requestUrl = decode(request.getRequestURL().toString());
        Optional<SpringWebProvider> springWebProviderOptional = springDocProviders.getSpringWebProvider();
        String prefix = StringUtils.EMPTY;
        if (springWebProviderOptional.isPresent())
            prefix = springWebProviderOptional.get().findPathPrefix(springDocConfigProperties);
        return requestUrl.substring(0, requestUrl.length() - apiDocsUrl.length() - prefix.length());
    }

}
